/**
 * 
 */
package com.module.hq.engine;

import com.dalonedrau.jogl.engine.GameState;
import com.dalonedrau.jogl.engine.Interactive;
import com.dalonedrau.jogl.engine.JOGLErrorHandler;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;
import com.module.hq.bus.globals.HQGlobals;
import com.module.hq.bus.globals.SpellConsts;
import com.rpg.base.Player;
import com.rpg.base.flyweight.Quest;
import com.rpg.base.flyweight.Scriptable;
import com.rpg.base.flyweight.Spell;
import com.rpg.base.globals.InterfaceGlobals;
import com.rpg.base.interactive.flyweight.BaseInteractiveObject;

/**
 * @author Donald
 */
public final class HQPlayer
		implements Player<HQInteractiveObject, HQCharacter> {
	public boolean hasPlayerVisitedRoom(final HQInteractiveObject playerIO, 
			final int roomId) {
		boolean has = false;
		try {
			PooledStringBuilder sb = 
				StringBuilderPool.getInstance().getStringBuilder();
			sb.append(HQScript.getInstance().getGlobalStringVariableValue(
							"currentMapName"));
			sb.append("_roomsVisited");
			int[] visited = 
				playerIO.getScript().getLocalVariable(sb.toString()).getIntArrayVal();
			System.out.println("player visited rooms ");
			for (int i = 0; i < visited.length; i++) {
				if (visited[i] == roomId) {
					has = true;
					break;
				}
			}
			visited = null;
			sb.returnToPool();	
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		return has;
	}
	/**
	 * Adds a room the IO has visited to its local variables.
	 * @param playerIO the player IO
	 * @param roomId the room's id
	 */
	public void addRoomVisited(final HQInteractiveObject playerIO, 
			final int roomId) {
		try {
			PooledStringBuilder sb = 
				StringBuilderPool.getInstance().getStringBuilder();
			sb.append(HQScript.getInstance().getGlobalStringVariableValue(
							"currentMapName"));
			sb.append("_roomsVisited");
			int[] visited = 
				playerIO.getScript().getLocalVariable(sb.toString()).getIntArrayVal();
			System.out.println("player visited rooms ");
			for (int i = 0; i < visited.length; i++) {
				System.out.println(visited[i]);
			}
			int[] dest = new int[visited.length + 1];
			System.arraycopy(
					visited, 0, dest, 0, visited.length);
			dest[visited.length] = roomId;
			visited = dest;
			dest = null;
			System.out.println("NOW player visited rooms ");
			for (int i = 0; i < visited.length; i++) {
				System.out.println(visited[i]);
			}
			playerIO.getScript().setLocalVariable(sb.toString(), visited);
			visited = null;
			visited = 
				playerIO.getScript().getLocalVariable(sb.toString()).getIntArrayVal();
			System.out.println("double-checking rooms ");
			for (int i = 0; i < visited.length; i++) {
				System.out.println(visited[i]);
			}
			sb.returnToPool();	
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/** the singeton instance of {@link HQPlayer}. */
	private static HQPlayer	instance;
	/**
	 * Gets the one and only instance of {@link HQPlayer}.
	 * @return {@link HQPlayer}
	 */
	public static HQPlayer getInstance() {
		if (HQPlayer.instance == null) {
			HQPlayer.instance = new HQPlayer();
		}
		return HQPlayer.instance;
	}
	/** the number of quest the player has assigned. */
	private int		numQuests;
	/** all the quests the player has assigned. */
	private Quest[]	playerQuests;
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addBag(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addGold(final HQInteractiveObject playerIO, final float val) {
		if (playerIO != null
				&& playerIO.hasIOFlag(HQGlobals.IO_01_PC)) {
			playerIO.getPCData().setGold(playerIO.getPCData().getGold() + val);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addInventoryBag(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addKey(final HQCharacter pc, final String key) {
		pc.addKey(key);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addQuest(final HQCharacter pc, final String quest,
			final boolean load) {
		if (playerQuests == null) {
			playerQuests = new Quest[0];
		}
		// FIGURE OUT HOW TO IMPLEMENT QUESTS
		numQuests++;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addRune(final HQCharacter pc) {
		// NOT USED
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void becomesDead(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean canStealItem(HQCharacter pc, HQInteractiveObject io) {
		// TODO Auto-generated method stub
		return false;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void combineKey(final HQCharacter pc, final HQInteractiveObject io)
			throws Exception {
		for (int i = 0; i < pc.getNumKeys(); i++) {
			/*
			int event = HQScript.getInstance().sendIOScriptEvent(io,
					HQGlobals.SM_24_COMBINE, pc.getKey(i), null);
			if (event == HQGlobals.REFUSE) {
				break;
			}
			*/
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void computePlayerFullStats(final HQInteractiveObject io)
			throws Exception {
		System.out.println("**********************");
		System.out.println("computePlayerFullStats");
		HQCharacter pc = io.getPCData();
		// clear all modifications
		pc.setModAttack(0);
		pc.setModBody(0);
		pc.setModDefend(0);
		pc.setModMind(0);
		pc.setModMovement(0);
		pc.setModMaxBody(0);
		pc.setModMaxMind(0);

		// IDENTIFY ALL EQUIPMENT AND APPLY MODS
		HQEquipment.getInstance().identifyAll(io);
		// Check for Equipment Modifiers to Attributes
		pc.adjModAttack(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_ATTACK,
				pc.getBaseAttack()
				));
		pc.adjModBody(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_BODY,
				pc.getBaseBody()
				));
		pc.adjModDefend(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_DEFEND,
				pc.getBaseDefend()
				));
		pc.adjModMind(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_MIND,
				pc.getBaseMind()
				));
		pc.adjModMovement(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_MOVEMENT,
				pc.getBaseMovement()
				));
		pc.adjModMaxBody(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_MAX_BODY,
				pc.getBaseMaxBody()
				));
		pc.adjModMaxMind(HQEquipment.getInstance().getEquipmentModifier(
				io,
				HQGlobals.IO_EQUIPITEM_ELEMENT_MAX_MIND,
				pc.getBaseMaxMind()
				));
		// Check for Equipment Modifiers to Skills
		// NOT USED
		// Check for Equipment Percent Modifiers to Skills
		// NOT USED
		// APPLY MODS FOR ALL SPELLS
		for (int i = 0; i < io.getNumberOfSpellsOn(); i++) {
			int spellId = io.getSpellOn(i);
			Spell spell = HQSpells.getInstance().getSpell(spellId);
			if (spell.exists()) {
				switch (spell.getType()) {
				case SpellConsts.SPELL_06_FIRE_COURAGE:
					pc.adjModAttack(2f);
					break;
				case SpellConsts.SPELL_05_EARTH_ROCK_SKIN:
					pc.adjModDefend(1f);
					break;
				case SpellConsts.SPELL_00_AIR_SWIFT_WIND:
					pc.adjModMovement(
							pc.getBaseMovement() + pc.getModMovement());
					break;
				default:
					break;
				}
			}
		}

		// SET FULL ATTRIBUTES
		pc.setFullAttack(pc.getBaseAttack() + pc.getModAttack());
		pc.setFullBody(pc.getBaseBody() + pc.getModBody());
		pc.setFullDefend(pc.getBaseDefend() + pc.getModDefend());
		pc.setFullMind(pc.getBaseMind() + pc.getModMind());
		pc.setFullMovement(pc.getBaseMovement() + pc.getModMovement());
		pc.setFullMaxBody(pc.getBaseMaxBody() + pc.getModMaxBody());
		pc.setFullMaxMind(pc.getBaseMaxMind() + pc.getModMaxMind());

		// SET PAPER DOLL
		/*
		 * if (pc.getBaseSize() >= 9 && pc.getBaseSize() <= 12) {
		 * pc.setHeight(RPGConsts.HEIGHT_00AVERAGE); } else if (pc.getBaseSize()
		 * >= 13) { pc.setHeight(RPGConsts.HEIGHT_01TALL); } if (pc.getGender()
		 * == RPGConsts.GENDER_FEMALE) { if (pc.getBaseConstitution() == 18) {
		 * pc.setMuscle(RPGConsts.MUSCLE_01MUSCULAR); } else if
		 * (pc.getBaseStrength() + pc.getBaseConstitution() >= 32) {
		 * pc.setMuscle(RPGConsts.MUSCLE_01MUSCULAR); } else {
		 * pc.setMuscle(RPGConsts.MUSCLE_00AVERAGE); } } else { if
		 * (pc.getBaseStrength() == 18) {
		 * pc.setMuscle(RPGConsts.MUSCLE_01MUSCULAR); } else if
		 * (pc.getBaseStrength() + pc.getBaseDexterity() >= 32) {
		 * pc.setMuscle(RPGConsts.MUSCLE_01MUSCULAR); } else {
		 * pc.setMuscle(RPGConsts.MUSCLE_00AVERAGE); } }
		 */
		pc.notifyWatchers();
		System.out.println("**********************");
		System.out.println("end computePlayerFullStats");
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void computePlayerStats(final HQCharacter pc) {
		// do nothing
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void forcePlayerLookAtIO(BaseInteractiveObject io) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void frameCheck(HQCharacter pc, float delay) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void frameUpdate(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void gameReset(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	public HQInteractiveObject getFreshHero(
			final Scriptable<HQInteractiveObject> script) throws Exception {
		HQInteractiveObject io =
				(HQInteractiveObject) Interactive.getInstance().getNewIO();
		io.setPCData(new HQCharacter());
		io.setScript(script);
		script.setIO(io);
		HQScript.getInstance().sendInitScriptEvent(io);
		return io;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public long getXPforLevel(int profession, int level) {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initializePlayer(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initKeyRing(final HQCharacter pc) {
		pc.setKeyring(null);
		pc.setNumKeys(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initQuest(final HQCharacter pc) {
		if (playerQuests != null) {
			for (int i = 0; i < numQuests; i++) {
				if (playerQuests[i] != null) {
					playerQuests[i].setIdent(null);
					playerQuests[i].setLocalised(null);
					playerQuests[i] = null;
				}
			}
			playerQuests = null;
		}
		numQuests = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initQuestFirst(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isInFightMode(final HQCharacter pc) {
		// if interface is comabt interface
		// or pc animations are combat animations, return true

		return pc.hasInterfaceFlag(InterfaceGlobals.INTER_COMBATMODE)
				|| GameState.getInstance().getCurrentState()
				== GameState.STATE_17HQ_IN_COMBAT;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void levelUp(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void loadHeroAnimations(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public HQCharacter makeAverageHero() {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public HQCharacter makeFreshHero() {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public HQCharacter makePowerfulHero() {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void manageDeath(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void manageMovement(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void manageVisual(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void modifyXP(HQCharacter pc, float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void modifyXP(HQCharacter pc, long val) {
		// TODO Auto-generated method stub

	}
	/**
	 * Creates a new character.
	 * @param name the character's name
	 * @param imageRef the character's image ref id
	 * @param attributes a list of the character's attributes
	 * @return {@link HQCharacter}
	 */
	public HQCharacter newCharacter(final String name, final int imageRef,
			final int... attributes) {
		HQCharacter pc = new HQCharacter();
		pc.setName(name);
		pc.setSpriteRef(imageRef);
		pc.setBaseAttack(attributes[0]);
		pc.setBaseBody(attributes[1]);
		pc.setBaseMaxBody(attributes[1]);
		pc.setBaseDefend(attributes[2]);
		pc.setBaseMind(attributes[3]);
		pc.setBaseMaxMind(attributes[3]);
		pc.setBaseMovement(attributes[4]);
		return pc;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void poison(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public HQCharacter quickGeneration() {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeInvisibility(final HQCharacter pc) {
		// DO NOTHING YET
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeRune(final HQCharacter pc) {
		// NOT USED
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void startNewQuest(HQCharacter pc) {
		// TODO Auto-generated method stub

	}
}
